﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;

namespace VSTweaker
{
    public class VisualStudioVersion
    {
        public VisualStudioVersion(string version, string instance)
        {
            this.Version = version;
            this.Instance = instance;

            if (Version == "10.0")
            {
                Name = "Visual Studio 2010";
            }
            else if (Version == "9.0")
            {
                Name = "Visual Studio 2008";
            }
            else if (Version == "8.0")
            {
                Name = "Visual Studio 2005";
            }
            else if (Version == "7.0")
            {
                Name = "Visual Studio 2003";
            }
            else
            {
                throw new ArgumentOutOfRangeException("version", "Unsupported Visual Studio version!");    
            }
            
        }

        public static IEnumerable<VisualStudioVersion> GetInstalledVersions()
        {
            var versions = new List<VisualStudioVersion>();

            var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);

            var vsKey = hklm.OpenSubKey("Software\\Wow6432Node\\Microsoft\\VisualStudio");

            if (vsKey == null)
            {
                throw new NullReferenceException("Visual Studio is not installed.");
            }
            
            try
            {
                var allKeys = vsKey.GetSubKeyNames().ToList();

                allKeys.Sort();

                foreach (var subKey in allKeys)
                {
                    float i;
                    if (float.TryParse(subKey, out i))
                    {
                        try
                        {
                            versions.Add(new VisualStudioVersion(subKey, string.Empty));

                            var instances = allKeys.Where(x => x.StartsWith(subKey) && x != subKey).Select(x => x.Substring(subKey.Length, x.Length - subKey.Length));

                            foreach (var instance in instances)
                            {
                                versions.Add(new VisualStudioVersion(subKey, instance));
                            }
                        }
                        catch (ArgumentOutOfRangeException)
                        {
                            
                        }
                        
                    }
                }
            }
            finally
            {
                vsKey.Close();
                vsKey.Dispose();
            }

            versions.Sort((x,y) => x.Version.CompareTo(y.Version) );

            return versions;
        }

        public bool Equals(VisualStudioVersion other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Equals(other.Version, Version);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof (VisualStudioVersion)) return false;
            return Equals((VisualStudioVersion) obj);
        }

        public override int GetHashCode()
        {
            return (Version != null ? Version.GetHashCode() : 0);
        }

        public override string ToString()
        {
            if (string.IsNullOrEmpty(this.Instance))
            {
                return this.Name;
            }
            else
            {
                return string.Format("{0} - {1}", this.Name, this.Instance);
            }
        }


        public string Name { get; set; }

        public string Version { get; set; }

        public string Instance { get; set; }
    }
}
